package com.knightcloud.common.oauth2.resource.config;

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;

import java.util.List;

/**
 * oauth2资源服务器配置
 *
 * @link <a href=
 * "https://docs.spring.io/spring-security/reference/servlet/oauth2/resource-server/jwt.html#oauth2resourceserver-jwt-sansboot">...</a>
 * @author knight
 */
@EnableWebSecurity
@EnableMethodSecurity
@Configuration(proxyBeanMethods = false)
public class Oauth2ResourceServerConfig {

	private final List<String> ignorePaths = List.of("/v3/api-docs", "/inner/**");

	@Bean
	@ConditionalOnProperty(name = "spring.security.oauth2.resourceserver.opaquetoken.introspection-uri")
	CustomOpaqueTokenIntrospector opaqueTokenIntrospector(OAuth2ResourceServerProperties properties) {
		OAuth2ResourceServerProperties.Opaquetoken opaqueToken = properties.getOpaquetoken();
		return new CustomOpaqueTokenIntrospector(opaqueToken.getIntrospectionUri());
	}

	@Bean
	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
		http.authorizeHttpRequests(authorize -> authorize
			// 放行
			.requestMatchers(ignorePaths.toArray(new String[] {}))
			.permitAll()
			// 其余路径校验
			.anyRequest()
			.authenticated())
			// 配置 OAuth 2.0 资源服务器 使用 opaqueToken/jwt由授权服务的访问令牌类型决定
			.oauth2ResourceServer(oauth2 -> oauth2.opaqueToken(Customizer.withDefaults()));
		return http.build();
	}

}
